---
description:
  Detect changes to your GraphQL Schema and prevent breaking your existing applications. With
  GraphQL Inspector you get a list of breaking, potentially dangerous and safe changes on every Pull
  Request.
---

import { Callout } from '@theguild/components'

# Diff and Validate GraphQL Schemas

Detect changes to your GraphQL Schema and prevent breaking your existing applications. With GraphQL
Inspector you get a list of breaking, potentially dangerous and safe changes on every Pull Request.
Integrate it with GitHub, BitBucket, GitLab or any Continuous Integration.

> While GraphQL Inspector is effective for comparing two schema versions and identifying changes,
> for a more comprehensive and robust approach to schema management, consider using
> [GraphQL Hive](https://the-guild.dev/graphql/hive). GraphQL Hive offers a fully open-source schema
> registry for GraphQL APIs. It provides features such as version control and schema checks to
> detect breaking changes before they reach production, allowing you to evolve your API with
> confidence. . Additionally, GraphQL Hive offers insights into API usage and performance metrics,
> making it a more robust solution for managing and evolving your GraphQL schemas.

![Application](/assets/img/github/app-action.jpg)

## You can choose between:

| Products                            | Description                                                                                                                |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [GitHub Action](../products/action) | Use our GitHub Action in few steps.                                                                                        |
| [CI](../products/ci)                | GraphQL Inspector offers a version of our CLI that is better suited for Continuous Integrations. Learn more how to use it. |
| [CLI](../installation#cli)          | GraphQL Inspector CLI is a simple tool to work with GraphQL schemas.                                                       |

## Diff - Usage

Run the following command:

```sh
graphql-inspector diff OLD_SCHEMA NEW_SCHEMA
```

### Arguments

- [`OLD_SCHEMA`](../api/schema) - point to an old schema
- [`NEW_SCHEMA`](../api/schema) - point to a new schema

### Flags

- `-r, --require <s>` - require a module
- `-t, --token <s>` - an access token
- `-h, --header <s>` - set http header (`--header 'Auth: Basic 123')
- `--method` - method on url schema pointers (default: `POST`)
- `--federation` - Support Apollo Federation V1 directives (default: `false`)
- `--federationV2` - Support Apollo Federation V2 directives (default: `false`)
- `--aws` - Support AWS Appsync directives and scalar types (default: `false`)

### Output

A list of all differences between two schemas. GraphQL Inspector defines three kinds of changes:

- Non-breaking change
- Dangerous Change
- Breaking change

When there's at least one breaking change, the process fails, otherwise, it succeeds.

## Examples

Compare your local schema against a remote server:

```sh
graphql-inspector diff https://api.com/graphql schema.graphql
```

Compare your local schema against a schema on a master branch (GitHub):

```sh
graphql-inspector diff github:user/repo#master:schema.graphql schema.graphql
```

## Rules

To customize the diff's behavior, you're able to use a set of rules:

### `dangerousBreaking`

Turns every dangerous change to be a breaking change.

```sh /--rule dangerousBreaking/
graphql-inspector diff https://api.com/graphql schema.graphql --rule dangerousBreaking
```

### `suppressRemovalOfDeprecatedField`

Every removal of a deprecated field is considered a breaking change. With that flag, you can turn it
into a dangerous change, so it won't fail a process or a CI check.

```sh /--rule suppressRemovalOfDeprecatedField/
graphql-inspector diff https://api.com/graphql schema.graphql --rule suppressRemovalOfDeprecatedField
```

Here is an example of a breaking change:

```graphql filename="OLD_SCHEMA"
type User {
  id: ID
  name: String
  age: Int @deprecated
}
```

```graphql filename="NEW_SCHEMA"
type User {
  id: ID
  name: String
}
```

- When "suppressRemovalOfDeprecatedField" rule enabled, it will not consider the removal of the
  `age` field as a breaking change.

### `ignoreDescriptionChanges`

Changes in descriptions are filtered out and are not displayed in the CLI result.

```sh /--rule ignoreDescriptionChanges/
graphql-inspector diff https://api.com/graphql schema.graphql --rule ignoreDescriptionChanges
```

### `safeUnreachable`

Breaking changes are done on unreachable parts of the schema (non-accessible when starting from the
root types) and won't be marked as breaking.

```sh /--rule safeUnreachable/
graphql-inspector diff https://api.com/graphql schema.graphql --rule safeUnreachable
```

Example of unreachable type:

```graphql
type Query {
  me: String
}

"""
User can't be requested, it's unreachable
"""
type User {
  id: ID!
}
```

### `considerUsage`

Decides if a breaking change is in fact breaking, based on real usage of schema.

```sh /--rule considerUsage --onUsage check-usage.js/
graphql-inspector diff https://api.com/graphql schema.graphql --rule considerUsage --onUsage check-usage.js
```

Example `check-usage.js` file:

```js filename="check-usage.js"
const BREAKING = false
const NOT_BREAKING = true

module.exports = entities => {
  return Promise.all(
    entities.map(async ({ type, field, argument }) => {
      // User                   => { type: 'User' }
      // Query.id               => { type: 'Query', field: 'me' }
      // Query.users(last: 10)  => { type: 'Query', field: 'users', argument: 'last' }
      const used = await checkIfUsedInLast30Days(type, field, argument)
      return used ? BREAKING : NOT_BREAKING
    })
  )
}
```

### Custom rules

It's possible to write your own rules.

First, you need a module:

```js filename="custom-rule.js"
module.exports = ({ changes }) => {
  return changes.filter(myCustomFilter)
}
```

Now, you can use that module as a rule:

```sh
graphql-inspector diff https://api.com/graphql schema.graphql --rule './custom-rule.js'
```

You can also write rules in TypeScript to take advantage of strict typing available in the package.

```ts filename="custom-rule.ts"
import type { Rule } from '@graphql-inspector/core'

const rule: Rule = ({ changes }) => {
  return changes.filter(myCustomFilter)
}

export default rule
```

You can then also use this module as a rule:

```sh
graphql-inspector diff https://api.com/graphql schema.graphql --rule './custom-rule.ts'
```

### Passing different headers to multiple remote schemas

If you want to do a diff between multiple remote schemas, each with a different set of
authentication headers, you can do it with `--left-header` and `--right-header` flags like so:

```sh
graphql-inspector diff http://your-schema-1/graphql http://your-schema-2/graphql --left-header 'Auth: Basic 123' --right-header 'Auth: Basic 345'
```

where `--left-header` will get passed to `http://your-schema-1/graphql` and `--right-header` will
get passed to `http://your-schema-2/graphql`.

<Callout>Note: `--left-header` and `--right-header` overrides the `--header` flags.</Callout>

## Support for Custom Directives

GraphQL Inspector offers enhanced support for custom directives, allowing users to easily detect
changes in directive usage within GraphQL schemas. This feature greatly improves the capabilities of
schema diffing, enabling comprehensive tracking of modifications related to custom directives across
different schema versions.

### How to Use

1. **Define Custom Directives:** Begin by defining custom directives within your GraphQL schemas.
   Specify their usage on various schema elements such as types, fields, arguments, and more.

```graphql
directive @customDirective on FIELD_DEFINITION
```

2. **Run Schema Diff:** Utilize the diff command provided by GraphQL Inspector. Specify the paths or
   URLs to the old and new schema files. Make sure that both schemas include the custom directives
   you want to track.

```bash
graphql-inspector diff OLD_SCHEMA NEW_SCHEMA
```

Replace `OLD_SCHEMA` and `NEW_SCHEMA` with the paths or URLs pointing to your old and new schemas
respectively.

3. **Review Changes:** After executing the diff command, GraphQL Inspector will analyze the schemas
   and identify any modifications related to custom directive usage. The output will provide
   detailed information about the detected changes, categorized based on their impact.

![Result](/assets/img/diff-result.png)

### Example

```graphql filename="OLD_SCHEMA"
input Foo {
  a: String
  b: String
}
```

```graphql filename="NEW_SCHEMA"
directive @foo on INPUT_FIELD_DEFINITION
input Foo {
  a: String @foo
  b: String
}
```

### Rules for Custom Directives

GraphQL Inspector's support for custom directives covers various schema elements, including:

- SCHEMA
- SCALAR
- OBJECT
- FIELD_DEFINITION
- ARGUMENT_DEFINITION
- INTERFACE
- UNION
- ENUM
- ENUM_VALUE
- INPUT_OBJECT
- INPUT_FIELD_DEFINITION
